#!/usr/bin/python3
import os

from neo4j import GraphDatabase, AsyncGraphDatabase, basic_auth, Driver, AsyncDriver
from settings import settings


# Neo4j 数据库操作类
class Neo4jProvider:
    """创建 Neo4j 数据库连接"""

    def __init__(self) -> None:
        # 获取环境变量值，如果没有就返回默认值
        self.url = settings.NEO4J_URI
        self.username = settings.NEO4J_USER
        self.password = settings.NEO4J_PASSWORD
        self.neo4j_version = settings.NEO4J_VERSION
        self.database = settings.NEO4J_DATABASE
        self.port = int(settings.NEO4J_PORT)

    # 同步驱动
    def driver(self) -> Driver:
        return GraphDatabase.driver(self.url, auth=basic_auth(self.username, self.password))

    # 异步驱动
    def async_driver(self) -> AsyncDriver:
        return AsyncGraphDatabase.driver(self.url, auth=basic_auth(self.username, self.password))

    def execute_query(self, cql):
        records, _, _ = driver.execute_query(
            cql,
            database_=self.database,
            routing_="r",
        )
        return records

    def delete_relationship(salf, l_node, r_node, relationship_name):
        """
        删除关系
        :param l_node: 左节点
        :param r_node: 右节点
        :param relationship_name: 关系
        :return:
        """
        """
        # 创建关系
        match(p:Symptom),(q:Examine) where p.name='上下楼梯疼' and q.name='膝关节核磁' create (p)-[rel:need_check{name:'症状检查'}]->(q)

        # 删除关系
        MATCH(p: Symptom)-[r: need_check]-(q:Examine)
        WHERE p.name = '上下楼梯疼' and q.name = '膝关节核磁'
        DELETE r
        """
        cql_del_rels = "MATCH(p:{})-[r:{}]-(q:{}) DELETE r".format(l_node, relationship_name, r_node)
        neo4j.execute_write(cql_del_rels)
        print("删除成功 => %s" % (cql_del_rels))

    def execute_write(self, cql):
        """
        执行写的命令
        :param cql: cql 语句
        :return:
        """
        with driver.session() as session:
            session.execute_write(execute_cql, cql)
        driver.close()


def execute_cql(tx, cql):
    """
    执行 CQL 语句
    :param tx:
    :param cql:
    :return:
    """
    tx.run(cql)


# 操作类对外暴露
neo4j = Neo4jProvider()

# 同步驱动。暴露给外面调用
driver = Neo4jProvider().driver()

# 异步驱动。暴露给外面调用
asyncDriver = Neo4jProvider().async_driver()
